package com.woniu.shiro;

import com.woniu.token.JWTFilter;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.Map;

/**
 * @author: mayuhang  <br/>
 * Date: 2021/5/21:9:57  <br/>
 * Description: shiro的配置类
 */
@Configuration
public class ShiroConfig {
    //配置安全管理器, 传入自己写的自定义域
    @Bean
    public DefaultWebSecurityManager securityManager(MyRealm realm) {
        //使用默认的安全管理器
        DefaultWebSecurityManager securityManager = new
                DefaultWebSecurityManager(realm);
        //将自定义的realm交给安全管理器统一调度管理
        securityManager.setRealm(realm);
        return securityManager;
    }
    //Filter工厂，设置对应的过滤条件和跳转条件 过滤器
    @Bean("shiroFilterFactoryBean")
    public ShiroFilterFactoryBean shirFilter(DefaultWebSecurityManager securityManager) {
        //1.创建shiro过滤器工厂
        ShiroFilterFactoryBean filterFactory = new ShiroFilterFactoryBean();
        //2.设置安全管理器
        filterFactory.setSecurityManager(securityManager);
        //3.通用配置,如果没有前后端分离配置这个（配置登录页面，登录成功页面，验证未成功页面）
//        filterFactory.setLoginUrl("/autherror?code=1"); //设置登录页面
//        filterFactory.setUnauthorizedUrl("/autherror?code=2"); //授权失败跳转页面
        //4.配置过滤器集合
        /**
         * key ：访问连接
         * 支持通配符的形式
         * value：过滤器类型
         * shiro常用过滤器类型
         * anon ：匿名访问（表明此链接所有人可以访问）
         * authc ：认证后访问（表明此链接需登录认证成功之后可以访问）
         */
//        Map<String,String> filterMap = new LinkedHashMap<String,String>();
        // 配置不会被拦截的链接 顺序判断
//        filterMap.put("/user/home", "anon");
//        filterMap.put("/login", "anon");
//        filterMap.put("/user/**", "authc");
        //5.设置自定义jwt过滤器
        Map<String, Filter> jwt = new HashMap<>();
        jwt.put("jwt",new JWTFilter());
        filterFactory.setFilters(jwt);

        /*
         * 6设置所有的请求都经过我们的JWTfilter
         * 自定义url规则
         * http://shiro.apache.org/web.html#urls-
         */
        Map<String, String> filterRuleMap = new HashMap<>();
        filterRuleMap.put("/login", "anon");
        filterRuleMap.put("/courseware/getCourseById", "anon");
        // 所有请求通过我们自己的JWT Filter
        filterRuleMap.put("/**", "jwt");
        filterFactory.setFilterChainDefinitionMap(filterRuleMap);
        return filterFactory;
    }
    //开启shiro注解支持
    @Bean
    public AuthorizationAttributeSourceAdvisor
    authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new
                AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }

    //管理Subject主体对象,生命周期的组件,用户只是打印下生产销毁日志什么的,请参考spring中bean的生命周期
    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
        return new LifecycleBeanPostProcessor();
    }

}
